package se.webbzon.boltzmann.environment;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import se.webbzon.boltzmann.debug.Debug;

public class VariableMap {
	
	// The variable maps of this player environment
	private final HashMap<String,Object> variableMap;

	/*============================================================
	Constructors
	============================================================*/
	
	/** Creates a new empty variable map. **/
	public VariableMap() {
		variableMap = new HashMap<String,Object>();
	}
	
	/*============================================================
	Public Methods
	============================================================*/
	
	/** Assigns the given string value to the variable with the given name.
	 * If the value of the assignment is null then the variable will
	 * be discarded from the variable map. The variable name is not 
	 * case sensitive. **/
	public void assign(String name, String value) {
		if (value == null)
			variableMap.remove(name.toUpperCase());
		else	{
			int d;
			Debug.debugMap(this, variableMap);
			variableMap.put(name.toUpperCase(),value);
		}
	}
	
	/** Assigns the given double value to the variable with the given name.
	 * If the value of the assignment is null then the variable will
	 * be discarded from the variable map. The variable name is not 
	 * case sensitive. **/
	public void assign(String name, Double value) {
		if (value == null)
			variableMap.remove(name.toUpperCase());
		else {	
			int d;
			Debug.debugMap(this, variableMap);
			variableMap.put(name.toUpperCase(),value);
		}
	}
	
	/** Returns the value of the variable with the given name. If the
	 * given variable is not yet assigned then null is returned. 
	 * The variable name is not case sensitive. **/
	public Object valueOf(String name) {
		return variableMap.get(name.toUpperCase());
	}
	
	/** Returns true if a value has been assigned the variable
	 * with the given name. The variable name is not case
	 * sensitive. **/
	public boolean isAssigned(String name) {
		return variableMap.containsKey(name.toUpperCase());
	}
	
	/** Returns all variable entries of the type Double. **/
	public ArrayList<VariableEntry<Double>> doubles() {
		ArrayList<VariableEntry<Double>> doubles = new ArrayList<VariableEntry<Double>>();
		Set<Map.Entry<String, Object>> entries = variableMap.entrySet();
		for (Map.Entry<String, Object> entry : entries) {
			if (entry.getValue() instanceof Double) {
				doubles.add(new VariableEntry<Double>(entry.getKey(), (Double) entry.getValue()));
			}
		}
		return doubles;
	}
	
	/** Returns all variable entries of the type String. **/
	public ArrayList<VariableEntry<String>> strings() {
		ArrayList<VariableEntry<String>> strings = new ArrayList<VariableEntry<String>>();
		Set<Map.Entry<String, Object>> entries = variableMap.entrySet();
		for (Map.Entry<String, Object> entry : entries) {
			if (entry.getValue() instanceof String) {
				strings.add(new VariableEntry<String>(entry.getKey(), (String) entry.getValue()));
			}
		}
		return strings;
	}

}
